import { getBrokenInternalLinks, renameFilesAndUpdateLinksInContent } from '@mintlify/link-rot';
import { dev } from '@mintlify/previewing';
import Chalk from 'chalk';
import path from 'path';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';

import { checkPort, checkForMintJson, checkNodeVersion } from './helpers.js';

export const cli = () =>
  yargs(hideBin(process.argv))
    .middleware(checkNodeVersion)
    .command(
      'dev',
      'Runs Mintlify project locally.',
      () => undefined,
      async (argv) => {
        const port = await checkPort(argv);
        if (port != undefined) {
          await dev({
            ...argv,
            port,
          });
        } else {
          console.error(`No available port found.`);
        }
      }
    )
    .command(
      'broken-links',
      'Check for broken links in your Mintlify project.',
      () => undefined,
      async () => {
        await checkForMintJson();

        console.log(Chalk.bold('Checking for broken links...\n'));

        const brokenLinks = await getBrokenInternalLinks();
        if (brokenLinks.length === 0) {
          console.log(Chalk.green('No broken links found.'));
          return;
        }

        const brokenLinksByFile: Record<string, string[]> = {};
        brokenLinks.forEach((mdxPath) => {
          const filename = path.join(mdxPath.relativeDir, mdxPath.filename);
          const brokenLinksForFile = brokenLinksByFile[filename];
          if (brokenLinksForFile) {
            brokenLinksForFile.push(mdxPath.originalPath);
          } else {
            brokenLinksByFile[filename] = [mdxPath.originalPath];
          }
        });
        Object.entries(brokenLinksByFile).forEach(([fileName, brokenLinks]) => {
          console.group(`${Chalk.underline(fileName)}`);
          console.log(brokenLinks.join('\n'), '\n');
          console.groupEnd();
        });
        console.error(Chalk.yellow(`${brokenLinks.length} broken links found.`));

        process.exit(1);
      }
    )
    .command(
      'rename <from> <to>',
      'Rename file in a Mintlify project and update the internal link references.',
      (yargs) =>
        yargs
          .positional('from', {
            describe: 'The file to rename',
            type: 'string',
          })
          .positional('to', {
            describe: 'The new name for the file',
            type: 'string',
          })
          .demandOption(['from', 'to'])
          .epilog('Example: `mintlify rename introduction.mdx overview.mdx`'),
      async ({ from, to }) => {
        await checkForMintJson();
        await renameFilesAndUpdateLinksInContent(from, to);
      }
    )
    // Print the help menu when the user enters an invalid command.
    .strictCommands()
    .demandCommand(1, 'Unknown command. See above for the list of supported commands.')

    // Alias option flags --help = -h, --version = -v
    .alias('h', 'help')
    .alias('v', 'version')

    .parse();
